#include "HuffmanTree.h"
using namespace  DataStruct;

#ifdef DEV_TEST
#include <gtest/gtest.h>
TEST(HuffmanTreeTest, getWPL)
{
	HuffmanTree<char, int> huffman_tree;
	std::unordered_map<char, int> elems;
	elems['A'] = 46;
	elems['B'] = 23;
	elems['C'] = 50;

	auto tree_root = huffman_tree.createHuffmanTree(elems);

	EXPECT_EQ(tree_root->getWPL(), 188);
}

TEST(HuffmanTreeTest, encodeAndDecode)
{
	HuffmanTree<char, int> huffman_tree;

	std::unordered_map<char, int> elems_frequency;

	std::string encode_str;
	std::string decode_str;
	for (int i = 0; i < 10000; ++i)
	{
		char ch = TestingUtil::randIntBetween(0, 26) + 'a';
		encode_str += ch;
		elems_frequency[ch]++;
	}

	huffman_tree.encodeBasedHuffmanTree(huffman_tree.createHuffmanTree(elems_frequency));

	std::vector<std::pair<int, int>> elems_vec;
	for (auto& kvp : elems_frequency)
		elems_vec.emplace_back(kvp.first, kvp.second);
	std::sort(elems_vec.begin(), elems_vec.end(),
		[](auto& left, auto& right)->bool {return left.second < right.second; });
	for (auto& kvp : elems_vec)
	{
		char elem = kvp.first;
		std::cout << elem << " : " << elems_frequency[elem] << " : " << huffman_tree.encode(elem) << std::endl;
	}

	std::string coding_str = huffman_tree.encode(encode_str);
	huffman_tree.decode(decode_str, coding_str);
	EXPECT_EQ(decode_str, encode_str);
}

TEST(HuffmanTreeTest, elemsEncode)
{
	HuffmanTree<char, int> huffman_tree;

	std::unordered_map<char, int> elems_frequency;
	elems_frequency['D'] = 15;
	elems_frequency['A'] = 27;
	elems_frequency['F'] = 5;
	elems_frequency['B'] = 8;
	elems_frequency['C'] = 15;
	elems_frequency['E'] = 30;

	huffman_tree.encodeBasedHuffmanTree(huffman_tree.createHuffmanTree(elems_frequency));

	std::vector<std::pair<int, int>> elems_vec;
	for (auto& kvp : elems_frequency)
		elems_vec.emplace_back(kvp.first, kvp.second);
	std::sort(elems_vec.begin(), elems_vec.end(),
		[](auto& left, auto& right)->bool {return left.second < right.second; });
	for (auto& kvp : elems_vec)
	{
		char elem = kvp.first;
		std::cout << elem << " : " << elems_frequency[elem] << " : " << huffman_tree.encode(elem) << std::endl;
	}
}
#endif